﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace reactiveBT.BT.Blackboard
{
    public class TreeValueList
    {
        //树变量表
        private Dictionary<string, dynamic> pairs;
        //试试看多播策略，少一层封装
        public Dictionary<string, TreeEvent> eventList;
        public TreeValueList()
        {
            pairs = new Dictionary<string, dynamic>();
        }
        public static TreeValueList operator +(TreeValueList valueList, KeyValuePair<string, dynamic> pair)
        {
            if (pair.Key == null)
            {
                throw new ArgumentNullException("不能在黑板上创建空参数名的变量");
            }
            else if (pair.Value == null)
            {
                throw new ArgumentException("不能将参数值置空");
            }
            else if (valueList.pairs.ContainsKey(pair.Key))
            {
                //这里先不抛出error，搞个log差不多得了
                Console.WriteLine("重复添加key，检查函数调用");
            }
            else
            {
                valueList.pairs[pair.Key] = pair.Value;
            }
            return valueList;
        }
        public static TreeValueList operator -(TreeValueList valueList, KeyValuePair<string, dynamic> pair)
        {
            if (pair.Key == null)
            {
                throw new ArgumentNullException("不能在黑板上删除空参数名的变量");
            }
            else if (pair.Value == null)
            {
                throw new ArgumentException("不能将参数值置空");
            }
            else if (!valueList.pairs.ContainsKey(pair.Key))
            {
                Console.WriteLine("重复删除key，检查函数调用");
            }
            else
            {
                valueList.pairs.Remove(pair.Key);
                if(valueList.eventList.ContainsKey(pair.Key))
                {
                    valueList.eventList[pair.Key].RemoveAll();
                    valueList.eventList.Remove(pair.Key);
                }
            }
            return valueList;
        }
        public Type GetValue(string name,ref dynamic result)
        {
            if (name == null || !pairs.ContainsKey(name))
            {
                return null;
            }
            result = pairs[name];
            return result.GetType();
        }
        public bool ChangeValue(string name, dynamic value)
        {
            //GetType方法待测试，不过有没有一种可能，能让我可以带着提示写代码呢？
            if (name == null || !pairs.ContainsKey(name))
            {
                var oldvalue = pairs[name];
                pairs[name] = value;
                eventList[name].Invoke(oldvalue, value, value.GetType());
                return true;
            }
            return false;
        }
        /// <summary>
        /// 单向绑定一个函数值
        /// </summary>
        /// <param name="name"></param>
        /// <param name="onValueChange"></param>
        /// <returns></returns>
        public bool BindValue(string name,Action<dynamic,dynamic,Type> onValueChange)
        {
            if(!pairs.ContainsKey(name))
            {
                Console.WriteLine("不能绑定不存在的值");
                return false;
            }
            if(!eventList.ContainsKey(name))
            {
                eventList[name] = new TreeEvent(onValueChange);
            }
            else
            {
                eventList[name].AddListener(onValueChange);
            }
            return true;
        }
        public bool UnbindValue(string name,Action<dynamic,dynamic,Type> onValueChange)
        {
            if(!pairs.ContainsKey(name))
            {
                Console.WriteLine("不能对不存在的变量解绑定");
                return false ;
            }
            eventList[name].RemoveListener(onValueChange);
            return true;
        }
    }
}
